/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.editor.ext; import java.awt.Rectangle; import java.awt.Font; import javax.swing.text.JTextComponent; import javax.swing.text.BadLocationException; import org.netbeans.editor.BaseCaret; import org.netbeans.editor.Coloring; import org.netbeans.editor.ExtUI; import org.netbeans.editor.MarkFactory; import org.netbeans.editor.DrawLayerFactory; import org.netbeans.editor.Utilities; import org.netbeans.editor.BaseDocument; import org.netbeans.editor.InvalidMarkException; import org.netbeans.editor.DrawContext; import org.netbeans.editor.DrawLayer; import org.netbeans.editor.Settings; import org.netbeans.editor.SettingsUtil; import org.netbeans.editor.SettingsChangeEvent; /** * Extended caret implementation * * @author Miloslav Metelka * @version 1.00 */ public class ExtCaret extends BaseCaret { /** Highlight row draw layer name */ public static final String HIGHLIGHT_ROW_LAYER_NAME = "highlight-row-layer"; // NOI18N /** Highlight row draw layer visibility */ public static final int HIGHLIGHT_ROW_LAYER_VISIBILITY = 1600; /** Highlight matching bracket draw layer name */ public static final String HIGHLIGHT_BRACKET_LAYER_NAME = "highlight-bracket-layer"; // NOI18N /** Highlight matching bracket draw layer visibility */ public static final int HIGHLIGHT_BRACKET_LAYER_VISIBILITY = 11000; /** Whether to highlight the background of the row * where the caret is. */ boolean highlightRow; /** Whether to hightlight the matching bracket */ boolean highlightBracket; /** Coloring used for highlighting the row where the caret is. */ Coloring highlightRowColoring; /** Coloring used for highlighting the matching bracket */ Coloring highlightBracketColoring; /** Mark holding the start of the line where the caret currently is. */ MarkFactory.DrawMark highlightRowMark; /** Mark holding the position of the matching bracket. */ MarkFactory.DrawMark highlightBracketMark; boolean bracketMarkValid; boolean simpleBracketMatching; static final long serialVersionUID =-4292670043122577690L; /** Called when settings were changed. The method is called * also in constructor, so the code must count with the evt being null. */ public void settingsChange(SettingsChangeEvent evt) { super.settingsChange(evt); JTextComponent c = component; if (c != null) { ExtUI extUI = Utilities.getExtUI(c); Class kitClass = Utilities.getKitClass(c); highlightRowColoring = extUI.getColoring(Settings.HIGHLIGHT_ROW_COLORING); highlightBracketColoring = extUI.getColoring(Settings.HIGHLIGHT_BRACKET_COLORING); highlightRow = SettingsUtil.getBoolean(kitClass, ExtSettings.HIGHLIGHT_CARET_ROW, false); highlightBracket = SettingsUtil.getBoolean(kitClass, ExtSettings.HIGHLIGHT_MATCHING_BRACKET, false); simpleBracketMatching = SettingsUtil.getBoolean(kitClass, ExtSettings.SIMPLE_BRACKET_MATCHING, true); } } public void install(JTextComponent c) { ExtUI extUI = Utilities.getExtUI(c); extUI.addLayer(new HighlightRowLayer()); extUI.addLayer(new HighlightBracketLayer()); super.install(c); } public void deinstall(JTextComponent c) { ExtUI extUI = Utilities.getExtUI(c); extUI.removeLayer(HIGHLIGHT_ROW_LAYER_NAME); extUI.removeLayer(HIGHLIGHT_BRACKET_LAYER_NAME); super.deinstall(c); } protected void update(Rectangle scrollRect, int scrollPolicy) { if (highlightRow || highlightBracket) { JTextComponent c = component; if (c != null) { ExtUI extUI = Utilities.getExtUI(c); BaseDocument doc = (BaseDocument)c.getDocument(); int dotPos = getDot(); if (highlightRow) { try { int bolPos = Utilities.getRowStart(doc, dotPos); if (highlightRowMark != null) { int markPos = highlightRowMark.getOffset(); if (bolPos != markPos) { extUI.repaintPos(markPos); Utilities.moveMark(doc, highlightRowMark, bolPos); extUI.repaintPos(bolPos); } } else { // highlight mark is null highlightRowMark = new MarkFactory.DrawMark(HIGHLIGHT_ROW_LAYER_NAME, extUI); highlightRowMark.setActivateLayer(true); Utilities.insertMark(doc, highlightRowMark, bolPos); extUI.repaintPos(bolPos); } } catch (BadLocationException e) { highlightRow = false; } catch (InvalidMarkException e) { highlightRow = false; } } try { boolean madeValid = false; if (highlightBracket && dotPos > 0) { int matchPos = doc.getSyntaxSupport().findMatchingBracket(dotPos - 1, simpleBracketMatching); if (matchPos >= 0) { if (highlightBracketMark != null) { int markPos = highlightBracketMark.getOffset(); if (markPos != matchPos) { extUI.repaintPos(markPos); Utilities.moveMark(doc, highlightBracketMark, matchPos); extUI.repaintPos(matchPos); } else { // on the same position if (!bracketMarkValid) { // was not valid, must repaint extUI.repaintPos(matchPos); } } } else { // highlight mark is null highlightBracketMark = new MarkFactory.DrawMark( HIGHLIGHT_BRACKET_LAYER_NAME, extUI); highlightBracketMark.setActivateLayer(true); Utilities.insertMark(doc, highlightBracketMark, matchPos); extUI.repaintPos(matchPos); } bracketMarkValid = true; madeValid = true; } } if (!madeValid) { if (bracketMarkValid) { bracketMarkValid = false; extUI.repaintPos(highlightBracketMark.getOffset()); } } } catch (BadLocationException e) { if (System.getProperty("netbeans.debug.exceptions") != null) { // NOI18N e.printStackTrace(); } highlightBracket = false; } catch (InvalidMarkException e) { if (System.getProperty("netbeans.debug.exceptions") != null) { // NOI18N e.printStackTrace(); } highlightBracket = false; } } } super.update(scrollRect, scrollPolicy); } /** Draw layer to highlight the row where the caret currently resides */ class HighlightRowLayer extends DrawLayerFactory.ColorLineLayer { public HighlightRowLayer() { super(HIGHLIGHT_ROW_LAYER_NAME, HIGHLIGHT_ROW_LAYER_VISIBILITY); } protected Coloring getColoring(DrawContext ctx) { return highlightRowColoring; } } /** Draw layer to highlight the matching bracket */ class HighlightBracketLayer extends DrawLayer { public HighlightBracketLayer() { super(HIGHLIGHT_BRACKET_LAYER_NAME, HIGHLIGHT_BRACKET_LAYER_VISIBILITY); } protected void init(DrawContext ctx) { active = bracketMarkValid; } protected void updateStatus(DrawContext ctx, MarkFactory.DrawMark mark) { if (mark != null) { if (bracketMarkValid) { active = true; setNextUpdateStatusPos(ctx.getOffset() + 1); } } else { active = false; } } protected void updateContext(DrawContext ctx) { if (highlightBracketColoring != null) { highlightBracketColoring.apply(ctx); Font f = ctx.getFont(); if (!f.isBold()) { ctx.setFont(f.deriveFont(f.getStyle() | Font.BOLD)); } } } } } /* * Log * 10 Gandalf-post-FCS1.8.1.0 3/8/00 Miloslav Metelka * 9 Gandalf 1.8 1/18/00 Miloslav Metelka * 8 Gandalf 1.7 1/13/00 Miloslav Metelka Localization * 7 Gandalf 1.6 1/11/00 Miloslav Metelka * 6 Gandalf 1.5 1/10/00 Miloslav Metelka * 5 Gandalf 1.4 1/4/00 Miloslav Metelka * 4 Gandalf 1.3 12/28/99 Miloslav Metelka * 3 Gandalf 1.2 11/27/99 Patrik Knakal * 2 Gandalf 1.1 11/11/99 Miloslav Metelka * 1 Gandalf 1.0 11/8/99 Miloslav Metelka * $ */